package XishiBackend.services.android;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import XishiBackend.base.Constant;
import XishiBackend.base.Json;
import XishiBackend.models.entity.Admin;
import XishiBackend.models.entity.Dishes;
import XishiBackend.models.entity.DishesType;
import XishiBackend.models.entity.Distribution;
import XishiBackend.models.entity.Order;
import XishiBackend.models.entity.Restaurant;
import XishiBackend.models.entity.User;
import XishiBackend.models.repository.AdminRepository;
import XishiBackend.models.repository.DishesRepository;
import XishiBackend.models.repository.DishesTypeRepository;
import XishiBackend.models.repository.DistributionRepository;
import XishiBackend.models.repository.OrderRepository;
import XishiBackend.models.repository.RestaurantRepository;
import XishiBackend.models.repository.UserRepository;

@Service
@Transactional
public class AndroidOrderService {
    @Autowired
    private OrderRepository oR;
    @Autowired
    private UserRepository uR;
    @Autowired
    private DishesRepository dishesR;
    @Autowired
    private RestaurantRepository rR;
    @Autowired
    private DistributionRepository distributionR;
    @Autowired
    private AdminRepository aR;
    @Autowired
    private DishesTypeRepository dtR;

    public List<Map<String, Object>> findOrderList(int status, long restaurantId, String time) {
        if(restaurantId == 0) {
            return orderList(
                    oR.findByStatusAndHasPaidAndUpdateTimeGreaterThanOrderByUpdateTimeDesc(status, Constant.PAID, time)
                    );
        }
        else {
            if( !rR.exists(restaurantId) ) {
                return null;
            }
            return orderList(
                    oR.findByRestaurantIdAndStatusAndHasPaidAndUpdateTimeGreaterThanOrderByUpdateTimeDesc(restaurantId, status, Constant.PAID, time)
                    );
        }
    }
    
    public List<Map<String, Object>> findOrderListWithAllStatus(long restaurantId, String time) {
        if(restaurantId == 0) {
            return orderList(
                    oR.findByHasPaidAndUpdateTimeGreaterThanOrderByUpdateTimeDesc(Constant.PAID, time)
                    );
        }
        else {
            if( !rR.exists(restaurantId) ) {
                return null;
            }
            return orderList(
                    oR.findByRestaurantIdAndHasPaidAndUpdateTimeGreaterThanOrderByUpdateTimeDesc(restaurantId, Constant.PAID, time)
                    );
        }
    }
    
    public Order findOne(long orderId) {
        return oR.findOne(orderId);
    }
    
    public boolean existOperator(long adminId) {
        return aR.exists(adminId);
    }
    
    public boolean save(Order o) {
        Order ro = oR.save(o);
        if(ro.getStatus() != o.getStatus()) {
            return false;
        }
        if(!ro.getUpdateTime().equals(o.getUpdateTime())) {
            return false;
        }
        if(ro.getOperatorId() != o.getOperatorId()) {
            return false;
        }
        return true;
    }
    
    public Map<String, Object> detail(long orderId) {
        Order o = oR.findOne(orderId);
        Distribution d = distributionR.findOne(o.getDistributionId());
        Map<String, Object> r = new HashMap<String, Object>();
        r.put("orderId", orderId);
        r.put("createTime", o.getCreateTime());
        r.put("takeNo", o.getTakeNo());
        r.put("tel", o.getTel());
        r.put("distributionName", d.getName());
        r.put("distributionAddress", d.getAddress());
        //获取全量菜品表
        Map<Long, String > dishesMap = new HashMap<Long, String>();
        Iterator<Dishes> iter = dishesR.findAll().iterator();
        while(iter.hasNext()) {
            Dishes item = iter.next();
            dishesMap.put(item.getId(), item.getName());
        }
        //解析菜品
        List<Map<String, Object>> dishesList = new ArrayList<Map<String, Object>>();
        Map<String, Integer> dishesJson = Json.decodeCar(o.getDishes());
        for(String key:dishesJson.keySet()) {
            long id = Long.parseLong(key);
            Map<String, Object> dishes = new HashMap<String, Object>();
            dishes.put("id", Long.parseLong(key));
            dishes.put("name", dishesMap.get(id));
            dishes.put("count", dishesJson.get(key));
            dishesList.add(dishes);
        }
        r.put("dishes", dishesList);
        
        r.put("remarks", o.getRemarks());
        r.put("totalPrice", o.getTotalPrice());
        r.put("orderType", Constant.PAY_TYPE[o.getOrderType()]);
        r.put("hasPaid",o.isHasPaid());
        r.put("cancelRemark", o.getCancelRemark());
        r.put("deliveryTime", o.getDeliveryTime());
        return r;
    }
    
    public Map<String, Object> findDishesById(long dishesId) {
        Dishes d = dishesR.findOne(dishesId);
        if(d == null) {
            return null;
        }
        Map<String, Object> r = new HashMap<String, Object>();
        r.put("id", d.getId());
        r.put("name", d.getName());
        r.put("description", d.getDescription());
        r.put("picture", d.getPicture());
        r.put("dishesType", dtR.findOne(d.getTypeId()).getName());
        r.put("price", d.getPrice());
        r.put("sales", d.getSales());
        r.put("discount", d.getDiscount());
        r.put("recommandType", Constant.RECOMMAND_TYPE[d.getRecommand()]);
        return r;
    }
    
    public User findUserByUserId(long userId) {
        return uR.findOne(userId);
    }
    
    public Distribution findDistributionById(long distributionId) {
        return distributionR.findOne(distributionId);
    }
    
    public Map<String, Object> orderOptimization(Order o) {
        Map<String, Map<Long,String>> map = getMap();
        
        Map<String, Object> m = new HashMap<String, Object>();
        m.put("orderId", o.getOrderId());
        m.put("takeNo", o.getTakeNo());
        m.put("tel", o.getTel());
        m.put("totalPrice", o.getTotalPrice());
        
        //获取全量菜品表
        Map<Long, String > dishesMap = new HashMap<Long, String>();
        Map<Long, Float > dishesPriceMap = new HashMap<Long, Float>();
        Iterator<Dishes> iter = dishesR.findAll().iterator();
        while(iter.hasNext()) {
            Dishes item = iter.next();
            dishesMap.put(item.getId(), item.getName());
            dishesPriceMap.put(item.getId(), item.getPrice());
        }
        //解析菜品
        List<Map<String, Object>> dishesList = new ArrayList<Map<String, Object>>();
        Map<String, Integer> dishesJson = Json.decodeCar(o.getDishes());
        for(String key:dishesJson.keySet()) {
            long id = Long.parseLong(key);
            Map<String, Object> dishes = new HashMap<String, Object>();
            dishes.put("id", Long.parseLong(key));
            dishes.put("name", dishesMap.get(id));
            dishes.put("price", dishesPriceMap.get(id));
            dishes.put("count", dishesJson.get(key));
            dishesList.add(dishes);
        }
        m.put("dishes", dishesList);
        //使用缓存查找各Id对应的名称
        m.put("restaurantId", o.getRestaurantId());
        m.put("distribution", map.get("distribution").get(o.getDistributionId()));
        m.put("operator", map.get("admin").get(o.getOperatorId()));

        m.put("orderType", o.getOrderType());
        
        List<Map<String,Object>> dishesTypeList = new ArrayList<Map<String,Object>>();
        Map<String,Integer> dtMap = Json.decodeCar(o.getDishesType());
        for(String key:dtMap.keySet()) {
            long id = Long.parseLong(key);
            Map<String, Object> item = new HashMap<String, Object>();
            item.put("id", id);
            item.put("name", map.get("dishesType").get(id));
            item.put("count", dtMap.get(key));
            dishesTypeList.add(item);
        }
        m.put("dishesType", dishesTypeList);
        m.put("createTime", o.getCreateTime());
        m.put("updateTime", o.getUpdateTime());
        m.put("status", o.getStatus());
        m.put("remark", o.getRemarks());
        m.put("cancelRemark", o.getCancelRemark());
        
        return m;
    }
    
    //将订单相关状态转成对应名称
    private List<Map<String, Object>> orderList(List<Order> oList) {
        List<Map<String,Object>> r = new ArrayList<Map<String, Object>>();
        Map<String, Map<Long,String>> map = getMap();
        for(Order o:oList) {
            Map<String, Object> m = new HashMap<String, Object>();
            m.put("orderId", o.getOrderId());
            m.put("takeNo", o.getTakeNo());
            m.put("tel", o.getTel());
            m.put("totalPrice", o.getTotalPrice());
            
            //使用缓存查找各Id对应的名称
            m.put("restaurantId", o.getRestaurantId());
            m.put("distribution", map.get("distribution").get(o.getDistributionId()));
            m.put("operator", map.get("admin").get(o.getOperatorId()));

            m.put("orderType", o.getOrderType());
            
            List<Map<String,Object>> dishesTypeList = new ArrayList<Map<String,Object>>();
            Map<String,Integer> dtMap = Json.decodeCar(o.getDishesType());
            for(String key:dtMap.keySet()) {
                long id = Long.parseLong(key);
                Map<String, Object> item = new HashMap<String, Object>();
                item.put("id", id);
                item.put("name", map.get("dishesType").get(id));
                item.put("count", dtMap.get(key));
                dishesTypeList.add(item);
            }
            m.put("dishesType", dishesTypeList);
            m.put("createTime", o.getCreateTime());
            m.put("updateTime", o.getUpdateTime());
            m.put("status", o.getStatus());
            m.put("remark", o.getRemarks());
            m.put("cancelRemark", o.getCancelRemark());
            m.put("deliveryTime", o.getDeliveryTime());
            
            r.add(m);
        }
        return r;
    }
    
    private Map<String, Map<Long,String>> getMap() {
        Map<String, Map<Long,String>> map = new HashMap<String,Map<Long,String>>();
        map.put("restaurant", new HashMap<Long,String>());
        map.put("distribution", new HashMap<Long,String>());
        map.put("admin", new HashMap<Long,String>());
        map.put("dishesType", new HashMap<Long,String>());
        
        Iterator<Restaurant> ri = rR.findAll().iterator();
        while(ri.hasNext()) {
            Restaurant r = ri.next();
            map.get("restaurant").put(r.getId(), r.getName());
        }
        Iterator<Distribution> di = distributionR.findAll().iterator();
        while(di.hasNext()) {
            Distribution d = di.next();
            map.get("distribution").put(d.getId(), d.getName());
        }
        Iterator<Admin> ai = aR.findAll().iterator();
        while(ai.hasNext()) {
            Admin a = ai.next();
            map.get("admin").put(a.getId(), a.getPersonName());
        }
        Iterator<DishesType> dti = dtR.findAll().iterator();
        while(dti.hasNext()) {
            DishesType dt = dti.next();
            map.get("dishesType").put(dt.getId(), dt.getName());
        }
        map.get("admin").put(0L, "用户");
        map.get("admin").put(99999L, "系统");
        
        return map;
    }
}
